#!coding=utf-8
import os
import time
import socket
from flask import Flask
from flask import jsonify
from flask import request
import json

from flask_cors import CORS, cross_origin
# 文件
from werkzeug.utils import secure_filename

# ip = '127.0.0.1'
ip = '172.20.39.82'

'''
API
	登录
	注册
	获取用户信息
'''

app = Flask("app", static_folder="assets",
            static_url_path="", template_folder="assets/html")
# 上传目录
UPLOAD_FOLDER = "assets/imgs"
ALLOWED_EXT = {'jpg', 'png', 'jpeg'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# Json 中文
app.config['JSON_AS_ASCII'] = False
# 跨域问题
cors = CORS(app)

'''
# 用户基本信息
{
	"account":"admin", // 登录账号
	"password" :"admin", // 登录密码
	"header":"http://172.20.39.82:5001/images/head.jpeg", // 头像地址
	"nick":"管理员", // 昵称
	"desc":"管理员不需要自我介绍", // 自我描述
	"birthday":"0000-00-00 00:00:00.000", // 生日 客户端 到日 即可
	"permission": -1, // 权限 , 数值越小, 能力越大
	"sex":0, // 性别: 0 没有设置; 1 男; 2 女
	"phone":"0576-90090000" // 电话 可以用来登录
}
# 请求体
{
	"time":"请求时间戳",
	"data":{}
}
# 响应体
{
	"msg":"",
	"code":0,
	"data":{}
}
'''

# 用户数据
table_user_list = [
    {
        "account": "admin",
        "password": "admin",
        "header": "http://172.20.39.82:5001/images/head.jpeg",
        "nick": "管理员",
        "desc": "管理员不需要自我介绍",
        "birthday": "0000-00-00 00:00:00.000",
        "permission": -1,
        "sex": 0,
        "phone": "0576-90090000"
    },
    {
        "account": "admin1",
        "password": "admin1",
        "header": "http://172.20.39.82:5001/images/head.jpeg",
        "nick": "管理员1",
        "desc": "管理员1不需要自我介绍",
        "birthday": "0000-00-00 00:00:00.000",
        "permission": -1,
        "sex": 0,
        "phone": "0576-90090001"
    },
    {
        "account": "admin2",
        "password": "admin2",
        "header": "http://172.20.39.82:5001/images/head.jpeg",
        "nick": "管理员2",
        "desc": "管理员2不需要自我介绍",
        "birthday": "0000-00-00 00:00:00.000",
        "permission": -1,
        "sex": 0,
        "phone": "0576-90090002"
    },
    {
        "account": "admin3",
        "password": "admin3",
        "header": "http://172.20.39.82:5001/images/head.jpeg",
        "nick": "管理员3",
        "desc": "管理员3不需要自我介绍",
        "birthday": "0000-00-00 00:00:00.000",
        "permission": -1,
        "sex": 0,
        "phone": "0576-90090003"
    },
    {
        "account": "admin4",
        "password": "admin4",
        "header": "http://172.20.39.82:5001/images/icon64_appwx_logo.png",
        "nick": "管理员4",
        "desc": "管理员4不需要自我介绍",
        "birthday": "0000-00-00 00:00:00.000",
        "permission": -1,
        "sex": 0,
        "phone": "0576-90090004"
    }
]

# 朋友关系 A -> B   === B -> A
"""
	{
		"from":"A.account",
		"to":"B.account",
		"commitTime":"0000-00-00 00:00:00.000",
		"addTime":"0000-00-00 00:00:00.000"
	}
"""
table_firends_list = [
    {
        "from": "admin",
        "to": "admin1",
        "commitTime": "0000-00-00 00:00:00.000",
        "addTime": "0000-00-00 00:00:00.000"
    },
    {
        "from": "admin2",
        "to": "admin",
        "commitTime": "0000-00-00 00:00:00.000",
        "addTime": "0000-00-00 00:00:00.000"
    }
]

# 申请添加 A -> B
# A 发起申请, B 查看通过后删除记录
"""
	{
		"from":"A.account", // 发起人
		"to":"B.account", // 添加对象
		"commitTime":"0000-00-00 00:00:00.000", // 申请事件
	}
"""
table_add_firends = [
    {
        "from": "admin2",
        "to": "admin3",
        "commitTime": "0000-00-00 00:00:00.000"
    },
    {
        "from": "admin4",
        "to": "admin2",
        "commitTime": "0000-00-00 00:00:00.000"
    }
]

# 聊天记录
table_msg_list = [
    {
        "content": "我是 Admin",
        "from": "admin",
        "to": "admin1",
        "sendTime": "0000-00-00 00:00:00.001",
        "receiveTime": "0000-00-00 00:00:00.001",
    },
    {
        "content": "我是 Admin1",
        "from": "admin1",
        "to": "admin",
        "sendTime": "0000-00-00 00:00:00.002",
        "receiveTime": "0000-00-00 00:00:00.002",
    },
]

table_msg_send_list = [
    {
        "content": "我是 Admin",
        "from": "admin",
        "to": "admin1",
        "sendTime": "0000-00-00 00:00:00.003"
    }
]

# ... 待拓展功能 表


# 路由测试
@app.route("/", methods=['GET', 'POST'])
def get_home():
    # 获取参数 -> Get
    # request.args.get('key')
    # request.values.get('key')
    # 获取参数 -> Post
    # application/json:
    # request.get_json()['content'] / request.json.get('centent')
    # request.get_data() 原始数据
    # multipart/form-data:
    # request.form.get('key') / request.form['key']
    # application/x-www-form-urlencoded:
    # request.values.get('key')
    return "Hello"


# 网页图标
@app.route("/favicon.ico", methods=["GET"])
def ico():
    return app.send_static_file("html/favicon.ico"), 200, []


# 获取 ./assets/html/ 下的 filename 文件
@app.route("/html/<path:filename>", methods=["GET"])
def html(filename):
    return app.send_static_file("html/"+filename), 200, []


# 获取 ./assets/html/ 下的 filename 文件 获取的网页资源 不能被其他网页 通过 iframe 嵌入
@app.route("/htmldeny/<path:filename>", methods=["GET"])
def htmlDeny(filename):
    return app.send_static_file("html/"+filename), 200, [("X-Frame-Options", "DENY")]


# 获取 ./assets/imgs/ 下的 filename 文件
@app.route("/images/<path:filename>", methods=["GET"])
def imgs(filename):
    return app.send_static_file("imgs/"+filename)


# 上传头像 图像文件 保存在 ./assets/imgs/ 目录下 , 通过 http://127.0.0.1:5001/images/filename 获取
@app.route("/uploader", methods=['POST'])
def uploader():
    if (request.method == 'POST'):
        f = request.files['file']
        f.save(os.path.join(
            app.config['UPLOAD_FOLDER'], secure_filename(f.filename)))

        print(f.filename)
        return jsonify({
            "msg": "上传成功",
            "code": 200,
            "data": "http://172.20.39.82:5001/images/" + f.filename
        })
    else:
        return jsonify({
            "msg": "非法请求",
            "code": 400,
            "data": None
        })


# 查询 account 的所有好友
def firend_list_by_account(account):
    firends = []
    # 获取所有的 好友关系
    for i in table_firends_list:
        if (i["from"] == account or i["to"] == account):
            firends.append(i)
    # 获取所有 好友列表
    firends_account = []
    for i in firends:
        if (i["from"] == account):
            # 添加 to 到 firends
            firends_account.append(i["to"])
        elif (i["to"] == account):
            # 添加 to 到 firends
            firends_account.append(i["from"])
    # 根据 好友名称列表 查询所有该用户到信息
    firends_info = []
    for i in firends_account:
        for j in table_user_list:
            if (i == j["account"]):
                # 找到用户 添加 -> 退出当前循环
                firends_info.append(j)
                continue
    return firends_info


# 查询 所有 account 用户 正在申请中的 用户列表
def apply_list_by_account(account):
    applyList = []
    for ap in table_add_firends:
        if ap["from"] == account or ap["to"] == account:
            applyList.append(ap)

    return applyList


# 查询当前用户 所有的好友列表
@app.route("/queryFirends", methods=['POST'])
def query_firends():
    params = request.get_data()
    params = json.loads(params)
    # 用户名 -> 查找朋友关系中 有这个 用户 到条目
    account = params["account"]
    firends = []
    # 获取所有的 好友关系
    for i in table_firends_list:
        if (i["from"] == account or i["to"] == account):
            firends.append(i)
    # 获取所有 好友列表
    firends_account = []
    for i in firends:
        if (i["from"] == account):
            # 添加 to 到 firends
            firends_account.append(i["to"])
        elif (i["to"] == account):
            # 添加 to 到 firends
            firends_account.append(i["from"])
    # 根据 好友名称列表 查询所有该用户到信息
    firends_info = []
    for i in firends_account:
        for j in table_user_list:
            if (i == j["account"]):
                # 找到用户 添加 -> 退出当前循环
                firends_info.append(j)
                continue
    return jsonify({
        "msg": "获取成功",
        "code": 200,
        "data": firends_info
    })


# user.account 是否包含 name
def query_username(name, user):
    return name in user.account


# 查找用户 返回包含用户输入关键字的 所有用户
@app.route("/queryUser", methods=['POST'])
def query_user():
    params = request.get_data()
    params = json.loads(params)
    # 当前用户
    account = params["account"]
    accountKey = params["accountKey"]
    # 过滤(区分) 本人/好友/已经申请/已经被申请/未申请 三种状态  0,1,2,3,4
    # 所有相关用户 : 默认 3 未申请-可添加好友
    queryUser = []
    for user in table_user_list:
        if (accountKey in user["account"]):
            queryUser.append(user)
    # 好友关系 不包含本人
    firendList = firend_list_by_account(account)
    # 申请关系 每条关系中都 至少 有一个 是本人的 account
    applyList = apply_list_by_account(account)
    for u in queryUser:
        u["state"] = 4
        if account == u["account"]:
            u["state"] = 0
            # 修改了当前用户后, 直接跳过当前循环 当前用户是有好友关系,并且有
            continue
        for firend in firendList:
            if u["account"] == firend["account"]:
                u["state"] = 1
                # 用户 u 在 当前用户的好友列表中
                break
        for apply in applyList:
            if u["account"] == apply["from"] and apply["to"] == account:
                # 用户 被 申请添加的
                u["state"] = 3
                # 当前
            elif u["account"] == apply["to"] and apply["from"] == account:
                # 用户 主动 申请添加的
                u["state"] = 2

    return jsonify({
        "msg": "获取成功",
        "code": 200,
        "data": queryUser
    })


# 添加好友 被申请的用户操作 同意
@app.route("/addFirend", methods=['POST'])
def add_firends():
    params = request.get_data()
    params = json.loads(params)
    # 请求添加 的 用户 / 被添加的用户
    fromUser = params["from"]
    toUser = params["to"]
    if fromUser == toUser:
        return jsonify({
            "msg": "自己不能添加自己",
            "code": 6000,
            "data": None
        })
    # 判断是否 已经是好友
    for firend in table_firends_list:
        if (firend["from"] == fromUser and firend["to"] == toUser):
            return jsonify({
                "msg": "请勿重复添加好友",
                "code": 6001,
                "data": None
            })
        elif (firend["from"] == fromUser and firend["to"] == toUser):
            return jsonify({
                "msg": "请勿重复添加好友",
                "code": 6001,
                "data": None
            })
    # 判断是否 已经申请添加过
    for firend in table_add_firends:
        if (firend["from"] == fromUser and firend["to"] == toUser):
            return jsonify({
                "msg": "请勿重复申请添加好友",
                "code": 6002,
                "data": None
            })
        elif (firend["from"] == toUser and firend["to"] == fromUser):
            return jsonify({
                "msg": "您已经被对方添加, 请前往同意",
                "code": 6002,
                "data": None
            })

    table_add_firends.append(params)
    return jsonify({
        "msg": "添加成功, 请等待对方同意好友申请",
        "code": 200,
        "data": None
    })


# 查询当前用户 被申请添加列表
@app.route("/queryAddList", methods=["POST"])
def query_add_list():
    params = request.get_data()
    params = json.loads(params)
    # 先拿到请求添加 account 的用户列表
    l = []
    for add in table_add_firends:
        if (add["to"] == params["account"]):
            l.append(add["from"])
    # 根据拿到的 List 获取用户的 详细信息
    addList = []
    for i in l:
        for user in table_user_list:
            if (user["account"] == i):
                addList.append(user)
                continue
    return jsonify({
        "msg": "获取成功",
        "code": 200,
        "data": addList
    })


# 同意添加好友
@app.route("/agreeFirends", methods=["POST"])
def agree_firends():
    params = request.get_data()
    params = json.loads(params)
    # 查找到添加条目
    af = None
    for addFirend in table_add_firends:
        if addFirend["from"] == params["from"] and addFirend["to"] == params["to"]:
            af = addFirend
    if af is None:
        return jsonify({
            "msg": "添加失败,没有查到相关申请",
            "code": 6001,
            "data": None
        })
    table_add_firends.remove(af)
    af["addTime"] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    table_firends_list.append(af)
    return jsonify({
        "msg": "添加成功",
        "code": 200,
        "data": None
    })


# 删除好友
@app.route("/deleteFirend", methods=["POST"])
def delete_firend():
    params = request.get_data()
    params = json.loads(params)

    itemFirend = None
    isAdd = False

    for firend in table_firends_list:
        if (firend["from"] == params["from"] and firend["to"] == params["to"]):
            itemFirend = firend

        if firend["from"] == params["from"] and firend["to"] == params["to"]:
            itemFirend = firend
            # 主动添加的可以删除
            isAdd = True
        if itemFirend != None:
            # 不再进行多余的判断
            break
    if isAdd:
        table_firends_list.remove(itemFirend)
        return jsonify({
            "msg": "删除成功",
            "code": 200,
            "data": None
        })
    else:
        return jsonify({
            "msg": "删除失败, 请联系好友进行删除操作",
            "code": 7001,
            "data": None
        })


# 获取所有用户信息
@app.route("/table/<path:tableName>", methods=['GET', "POST"])
def query_table(tableName):
    tabInfo = None
    if tableName == "user":
        tabInfo = table_user_list
    elif tableName == "firends":
        tabInfo = table_firends_list
    elif tableName == "add":
        tabInfo = table_add_firends
    elif tableName == "msg":
        tabInfo = table_msg_list
    return jsonify({
        "msg": "获取 Table 成功",
        "code": 200,
        "data": tabInfo
    })


# 获取所有用户信息
@app.route("/allUser", methods=['POST'])
def all_user():
    return jsonify({
        "msg": "获取成功",
        "code": 200,
        "data": table_user_list
    })


# 校验用户 判断用户是否已经注册 account 和 phone 有任意一个视为被注册
def check_user(account, phone):
    for u in table_user_list:
        if (u["account"] == account):
            return 4001
        if (u["phone"] == phone):
            return 4002
    return 200


# 注册校验 注册用户的 account / phone 在列表中必须唯一
@app.route("/registerCheck", methods=['POST'])
def check_register():
    # 获取输入手机号 登录所用用户名 检验是否可以进行注册
    # -> 接口调用时机 在用户输入框失去焦点后调用
    params = request.get_data()
    params = json.loads(params)
    print(params["account"])
    print(params["phone"])
    for u in table_user_list:
        if (u["account"] == params["account"]):
            return jsonify({
                "msg": "登录名称已占用",
                "code": 4001,
                "data": None
            })
        if (u["phone"] == params["phone"]):
            return jsonify({
                "msg": "手机号已占用",
                "code": 4002,
                "data": None
            })
    return jsonify({
        "msg": "登录名称和手机号通过测试",
        "code": 200,
        "data": None
    })


# 注册用户 注册成功后  返回用户信息
@app.route("/register", methods=['POST'])
def register():
    # 获取注册手机号 登录用户名密码 检验是否可以进行注册 -> 接口调用时机 在用户输入
    params = request.get_data()
    params = json.loads(params)
    # 再次 check
    errCode = check_user(params["account"], params["phone"])
    if (errCode != 200):
        return jsonify({
            "msg": "注册失败",
            "code": errCode,
            "data": None
        })
    user = {
        "account": params["account"],
        "password": params["password"],
        "header": params["header"],
        "nick": params["nick"],
        "desc": params["desc"],
        "birthday": params["birthday"],
        "permission": params["permission"],
        "sex": params["sex"],
        "phone": params["phone"]
    }
    # 添加用户到 list
    beList = len(table_user_list)
    table_user_list.append(user)
    afList = len(table_user_list)
    # 判断添加结果
    if (afList == beList + 1):
        return jsonify({
            "msg": "用户注册成功",
            "code": 200,
            "data": user
        })
    else:
        return jsonify({
            "msg": "用户注册失败",
            "code": 5001,
            "data": None
        })


# 用户登录 返回用户信息
@app.route("/login", methods=['POST'])
def login():
    params = request.get_data()
    params = json.loads(params)
    print(params["account"])
    print(params["password"])
    for u in table_user_list:
        if (u["account"] == params["account"]):
            if (u["password"] == params["password"]):
                return jsonify({
                    "msg": "登录成功",
                    "code": 200,
                    "data": u
                })
            else:
                return jsonify({
                    "msg": "用户密码错误",
                    "code": 5001,
                    "data": None
                })
    return jsonify({
        "msg": "用户不存在",
        "code": 5002,
        "data": None
    })


# 获取用户信息
@app.route("/user", methods=['POST'])
def get_user():
    params = request.get_data()
    params = json.loads(params)
    print(params["account"])
    for u in table_user_list:
        if (u["account"] == params["account"]):
            return jsonify({
                "msg": "获取用户信息成功",
                "code": 200,
                "data": u
            })
    return jsonify({
        "msg": "请求用户信息失败",
        "code": 5002,
        "data": None
    })


"""
	"account":"admin", // 登录账号
	"password" :"admin", // 登录密码
	"header":"http://172.20.39.82:5001/images/head.jpeg", // 头像地址
	"nick":"管理员", // 昵称
	"desc":"管理员不需要自我介绍", // 自我描述
	"birthday":"0000-00-00 00:00:00.000", // 生日 客户端 到日 即可
	"permission": -1, // 权限 , 数值越小, 能力越大
	"sex":0, // 性别: 0 没有设置; 1 男; 2 女
	"phone":"0576-90090000" // 电话 可以用来登录
"""


# 校验修改信息  account 不可修改, 只对比 phone
def check_edit_user(account, phone):
    for u in table_user_list:
        if (u["account"] == account):
            # 用户相等 时 跳过对比 手机号
            continue
        if (u["phone"] == phone):
            return 4002
    return 200


# 修改用户信息 account 不可修改 作为唯一标识
@app.route("/editUser", methods=["POST"])
def edit_info():
    params = request.get_data()
    params = json.loads(params)
    print(params)
    for u in table_user_list:
        # 判断手机号
        if u["account"] == params["account"]:
            # 这里是全部 肯定不通过
            errCode = check_edit_user(params["account"], params["phone"])
            if errCode == 200:
                # 校验通过
                u["password"] = params["password"]
                u["header"] = params["header"]
                u["nick"] = params["nick"]
                u["birthday"] = params["birthday"]
                # 权限 应该放在另一个接口中, 申请权限提升, 较为合理 这里先直接修改
                u["permission"] = params["permission"]
                u["sex"] = params["sex"]
                # 修改后的 手机号 依旧要保证唯一性 因为可以使用这个手机号进行登录
                u["phone"] = params["phone"]
                return jsonify({
                    "msg": "获取用户信息成功",
                    "code": 200,
                    "data": u
                })
            else:
                return jsonify({
                    "msg": "修改失败",
                    "code": errCode,
                    "data": None
                })
    # 没有找到 用户信息
    return jsonify({
        "msg": "修改失败",
        "code": 5002,
        "data": None
    })


# 聊天列表 先查询 待发送列表, 再查询 消息列表
@app.route("/chatList", methods=["POST"])
def chat_list():
    params = request.get_data()
    params = json.loads(params)
    print(params)
    # 获取为接收到消息(用户没有进入和 from 用户 到聊天界面相当于没有接收该消息)
    chatList = []
    # 查询 (发送给用户信息 用户还没有接收) 的用户
    chatUser = []
    for send in table_msg_send_list:
        if send["to"] == params["account"]:
            if send["from"] not in chatUser:
                chatUser.append(send["from"])
    for msg in table_msg_list:
        if msg["to"] == params["account"]:
            if msg["from"] not in chatUser:
                chatUser.append(msg["from"])
    # 把用户名称列表转为用户信息列表
    for i in chatUser:
        for j in table_user_list:
            if j["account"] == i:
                chatList.append(j)
                break
    return jsonify({
        "msg": "获取聊天用户列表成功",
        "code": 200,
        "data": chatList
    })


# 发送消息: 发送的消息 将保存在 带发送消息列表中 table_msg_send_list 中
@app.route("/sendMsg", methods=["POST"])
def send_msg():
    params = request.get_data()
    params = json.loads(params)
    print(params)
    sendMsg = {
        "content": params["content"],
        "from": params["from"],
        "to": params["to"],
        "sendTime": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    }
    table_msg_send_list.append(sendMsg)
    return jsonify({
        "msg": "发送成功",
        "code": 200,
        "data": sendMsg
    })


# 接收消息: 从 table_msg_send_list 中取出数据, 加入到 msg 中
# 需要 from 和 to 两个用户
@app.route("/receiveMsg", methods=["POST"])
def receive_msg():
    params = request.get_data()
    params = json.loads(params)
    print(params)
    msgList = []
    historyList = []
    # 判断是否要包含 历史消息
    if params["hasHistory"] is True:
        for msg in table_msg_list:
            if (msg["from"] == params["from"] and msg["to"] == params["to"]) or (msg["from"] == params["to"] and msg["to"] == params["from"]):
                historyList.append(msg)
    # 获取所有 到 未请求的消息
    for receive in table_msg_send_list:
        # 接收 新的消息
        if receive["from"] == params["from"] and receive["to"] == params["to"]:
            msgList.append(receive)
        # 查询用户发送的消息, 也保存在这, 也要查询并返回 只获取一次, hasHistory
        if receive["from"] == params["to"] and receive["to"] == params["from"] and params["hasHistory"] is True:
            msgList.append(receive)
    for msg in msgList:
        # 从 send 队列中移除 (只能移除 msg["to"] 是当前查询用户的, 不能移除用户发送的)
        if msg["to"] == params["to"]:
            table_msg_send_list.remove(msg)
            # 添加 接收时间
            msg["receiveTime"] = time.strftime(
                '%Y-%m-%d %H:%M:%S', time.localtime())
            # 加入 到消息队列中
            table_msg_list.append(msg)
    returnMsgList = historyList + msgList
    print(returnMsgList)
    # 组合消息
    return jsonify({
        "msg": "查询成功",
        "code": 200,
        "data": returnMsgList
    })


# 启动服务器
app.run(host='0.0.0.0', port=5001)
